/*
 * Copyright 2012 jsm.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.abiwebz.office.rm.database.configuration;

import java.awt.BorderLayout;
import java.awt.Component;
import java.beans.PropertyChangeListener;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComponent;
import javax.swing.JPanel;
import net.abiwebz.office.rm.database.DatabaseDriver;
import net.abiwebz.office.rm.database.DatabaseDrivers;
import net.abiwebz.office.rm.database.util.IWizardStoreRead;
import org.openide.WizardDescriptor;

public final class DbConfigVisualPanel2 extends JPanel implements IWizardStoreRead {

    public static final String PROP_ONLINE_DRIVER = "online_driver";
    
    private DriverConfigurationPanel configPanel;
    private boolean importFlag;
    
    /**
     * Creates new form DbConfigVisualPanel2.
     */
    public DbConfigVisualPanel2() {
        initComponents();
        Object[] drivers = DatabaseDrivers.get().toArray();
        cbDrivers.setModel(new DefaultComboBoxModel<Object>(drivers));
        updateDriverConfigurationPanel();
    }

    /**
     * Return the displayed name for this page.
     * 
     * @return The name used for display
     */
    @Override
    public String getName() {
        return "Online database";
    }
    
    /**
     * Get the selected database driver from the combobox.
     * 
     * @return The selected DatabaseDriver
     */
    public DatabaseDriver getDriver(){
        return (DatabaseDriver)cbDrivers.getSelectedItem();
    }
    
    /**
     * Get the current driver configuration panel. This panel is already
     * loaded and visible. The panel is different for each DatabaseDriver but
     * functions are always the same.
     * 
     * @return The panel containing the configuration for the driver.
     */
    public DriverConfigurationPanel getDriverConfiguration(){
        return configPanel;
    }
    
    /**
     * Draw the Driver configuration panel for the selected driver.
     * This way we can have special configuration for every drivers, we are not
     * bound to specific creation patterns.
     */
    private void updateDriverConfigurationPanel(){
        DatabaseDriver driver = (DatabaseDriver) cbDrivers.getSelectedItem();
        pDriverConfigPanel.removeAll(); // Remove already existing panel
        configPanel = driver.getConfigurationPanel(driver);
        for(PropertyChangeListener l : this.getPropertyChangeListeners()){
            configPanel.addPropertyChangeListener(l);
        }
        pDriverConfigPanel.add(configPanel, BorderLayout.CENTER);
        validate(); // Redraw the configuration panel
        firePropertyChange(PROP_ONLINE_DRIVER, 0, 1);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lDatabaseDriver = new javax.swing.JLabel();
        cbDrivers = new javax.swing.JComboBox<Object>();
        jSeparator1 = new javax.swing.JSeparator();
        pDriverConfigPanel = new javax.swing.JPanel();

        org.openide.awt.Mnemonics.setLocalizedText(lDatabaseDriver, org.openide.util.NbBundle.getMessage(DbConfigVisualPanel2.class, "DbConfigVisualPanel2.lDatabaseDriver.text")); // NOI18N

        cbDrivers.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbDriversActionPerformed(evt);
            }
        });

        pDriverConfigPanel.setLayout(new java.awt.BorderLayout());

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jSeparator1)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lDatabaseDriver)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cbDrivers, 0, 354, Short.MAX_VALUE)
                .addContainerGap())
            .addComponent(pDriverConfigPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lDatabaseDriver)
                    .addComponent(cbDrivers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pDriverConfigPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Event fired when we change the selected driver. We need to update 
     * the panel used to configure the driver replacing it with the new one.
     * 
     * @param evt ActionEvent fired by the driver combobox
     */
    private void cbDriversActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbDriversActionPerformed
        if(evt.getActionCommand().equals("comboBoxChanged")){
            updateDriverConfigurationPanel();
        }
    }//GEN-LAST:event_cbDriversActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox<Object> cbDrivers;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JLabel lDatabaseDriver;
    private javax.swing.JPanel pDriverConfigPanel;
    // End of variables declaration//GEN-END:variables

    /**
     * Read data from other pages of the wizard.
     * 
     * @param wiz WizardDescriptor containing the wizard values
     */
    @Override
    public void read(WizardDescriptor wiz) {
        // Nothing to read
        importFlag = (Boolean) wiz.getProperty(DbConfigVisualPanel1.PROP_IMPORT_CHECK);
    }

    /**
     * Store data from this page of the wizard.
     * 
     * @param wiz WizardDescriptor containing the wizard values
     */
    @Override
    public void store(WizardDescriptor wiz) {
        if(!importFlag){
            wiz.putProperty(PROP_ONLINE_DRIVER, getDriver().getDriverID());
            wiz.putProperty("online_" + DriverConfigurationPanel.PROP_JDBC_URL, getDriverConfiguration().getJDBCUrl());
        }
        //System.out.println("Saving : " + getDriverConfiguration().getJDBCUrl());
    }
    
    /**
     * Enable or disable all components in the JComponent. If a component
     * contains components the we call this function again until all components
     * have changed.
     * 
     * @param c The root JComponent
     * @param enabled True if the new state is enabled
     */
    private void enableComponents(JComponent c, boolean enabled){
        if(c.getComponentCount() > 0){
            Component[] components = c.getComponents();
            for(Component cwork : components){
                if(cwork instanceof JComponent)
                    enableComponents((JComponent)cwork, enabled);
                else
                    cwork.setEnabled(enabled);
            }
        }
        c.setEnabled(enabled);
    }
    
    /**
     * Enable or disable all components in this panel. If a component
     * contains components the we call this function again until all components
     * have changed.
     * 
     * @param enabled True if the new state is enabled
     */
    public void enableComponents(boolean enabled){
        enableComponents(this, enabled);
    }
}
